package Server.ServerCore.Service.syns;

import Server.ExtComponents.BaseConfig.MServerConfig;
import Server.ServerCore.Model.AI.BankerAI;
import Server.ServerCore.Model.Player.GameCharacter;

import Server.ServerCore.Model.Player.PlayerInstance;
import Server.ServerCore.Service.hardCode.HadlerStatus;
import Server.ServerCore.Service.hardCode.TableStatus;
import javolution.util.FastList;
import org.jboss.netty.buffer.ChannelBuffer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Observable;
import java.util.Observer;
import java.util.Vector;

/**
 * @author :石头哥哥<br/>
 *         Project:21Server
 *         Date: 13-4-2
 *         Time: 上午10:02
 *         Table
 *
 *    this is a syns interface!inculds Table and TableManager classes.
 */

public class Table{
    private static final Logger LOG = LoggerFactory.getLogger(Table.class);
    private int TableID;//牌桌编号
    private BankerAI banker;//庄,初始化table就存在庄家

    private FastList<CircleUnit> circleUnitFastList=new FastList<CircleUnit>(6);//每个牌桌上的CircleUnit对象列表，玩家位置，从右向左0，1，2，3，4,编号和
    private  FastList<GameCharacter> gameCharacterFastList = new FastList<GameCharacter>(6); //游戏对象

    // TableStatus
    private  static final  ThreadLocal<TableStatus> threadLocal=new ThreadLocal<TableStatus>();//TableStatus threadLocal

    public Table(int tableID){
        this.setTableID(tableID);
        for (int i=0;i!=6;++i){//
            circleUnitFastList.add(new CircleUnit(i));
        }
    }
    /**
     * 设定对象在地图上的状态 变量
     * @param mapStatus         MapStatus
     */
    public void setTableStatus(TableStatus mapStatus){
        threadLocal.set(mapStatus);
    }

    /**
     * 获取对象在地图上的状态 变量
     * @return   MapStatus
     */
    public TableStatus getCurrentTableStatus() {
        return  threadLocal.get();
    }

    /**
     * 对象在地图上的状态 变量
     * 清除当前线程中的值，显示的调用，加快内存的回收
     */
    public void remove(){
        threadLocal.remove();
    }


    /**
     *
     * @param gameCharacter  活动对象
     * @param CircleUnitUnitID  gameCharacter所在牌桌的CircleUnitUnitID---通过房间匹配模式
     */
    public void logicHandle(GameCharacter gameCharacter,int CircleUnitUnitID){
        switch (this.getCurrentTableStatus()){
            case INTO_TABLE:
                if(MServerConfig.debug) LOG.info("【"+gameCharacter+"】"+gameCharacter.getID()+":进入牌桌......");
                circleUnitFastList.get(CircleUnitUnitID).addPlyaer(gameCharacter);
                this.remove();
                break;
            case LEAVE_TABLE:
                if(MServerConfig.debug) LOG.info("【"+gameCharacter+"】"+gameCharacter.getID()+":离开牌桌......");
                circleUnitFastList.get(CircleUnitUnitID).delPlayer(gameCharacter);
                this.remove();
                break;
            default:
                if(MServerConfig.debug) LOG.info("Maybe this is a bug please action!!");
                break;
        }
    }


    public FastList<CircleUnit> getCircleUnitFastList() {
        return circleUnitFastList;
    }

    public void setCircleUnitFastList(FastList<CircleUnit> circleUnitFastList) {
        this.circleUnitFastList = circleUnitFastList;
    }


    public BankerAI getBanker() {
        return banker;
    }

    public void setBanker(BankerAI banker) {
        this.banker = banker;
    }


    public int getTableID() {
        return TableID;
    }

    public void setTableID(int tableID) {
        TableID = tableID;
    }
    public FastList<GameCharacter> getGameCharacterFastList() {
        return gameCharacterFastList;
    }

//每一个CircleUnit即是观察者也是被观察者
@SuppressWarnings("unchecked")
public class CircleUnit extends Observable implements Observer {

        private int circleUnitID;  //编号
        private boolean Occupancy;//占用状态

        public CircleUnit(int circleUnit){
            super();
            this.circleUnitID=circleUnit;
            this.setOccupancy(false);//没有被占用
            addObserver(this);//添加观察者
        }

        public void addPlyaer(GameCharacter gameCharacter){
            gameCharacterFastList.add(gameCharacter);
            setChanged();
            Vector vector = new Vector();
            vector.add(HadlerStatus.ADD);
            vector.add(gameCharacter);
            notifyObservers(vector);
        }


        public void delPlayer(GameCharacter gameCharacter){
            gameCharacterFastList.remove(gameCharacter);//移除player
            this.setOccupancy(false);
            setChanged();
            Vector vector = new Vector();
            vector.add(HadlerStatus.DELETE);
            vector.add(gameCharacter);
            notifyObservers(vector);
        }


        public void SendSynMsg(GameCharacter gameCharacter, ChannelBuffer buffer) {
                setChanged();
                Vector obj = new Vector();
                obj.add(HadlerStatus.SEND);//0
                obj.add(gameCharacter);//1
                obj.add(buffer);//2
                notifyObservers(obj);
        }

        @Override
        public void update(Observable o, Object arg) {
            Vector vector = null;
            if (arg != null) {
                vector = (Vector) arg;
            }
            if (vector!=null){
                switch ((HadlerStatus) vector.get(0)){
                    case ADD:
                        palayerJoin(vector);        //对象加入
                        break;
                    case DELETE:
                        palayerleave(vector);      //对象离开
                        break;
                    case SEND:
                        palayerMessageSend(vector);       //对象状态信息
                        break;
                    default:
                        break;
                }
            }else {
                return;
            }
        }
    //对象离开
        private void palayerleave(Vector vector) {
            GameCharacter gameCharacter= (GameCharacter) vector.get(1);
            if (gameCharacter instanceof PlayerInstance){//同步玩家信息
                PlayerInstance player= (PlayerInstance) gameCharacter;
                for (GameCharacter playerInstance:getGameCharacterFastList()){//向玩家同步gameCharacter的信息
                    if (playerInstance.getID()==player.getID()||playerInstance instanceof BankerAI)continue;

                    //构造bean将player信息推送出去
                    playerInstance.DirectSend(null);
                }
            }

        }
        //对象加入
        private void palayerJoin(Vector vector) {
            GameCharacter gameCharacter= (GameCharacter) vector.get(1);
            if (gameCharacter instanceof PlayerInstance){//同步玩家信息
                PlayerInstance player= (PlayerInstance) gameCharacter;
                for (GameCharacter playerInstance:getGameCharacterFastList()){//向玩家同步gameCharacter的信息
                    if (playerInstance.getID()==player.getID()||playerInstance instanceof BankerAI)continue;

                    //构造bean将player信息推送出去
                    playerInstance.DirectSend(null);
                }
            }
        }


        //对象状态信息发送  bankerAI,plyaer
        private void palayerMessageSend(Vector vector) {
            GameCharacter gameCharacter= (GameCharacter) vector.get(1);
            ChannelBuffer data= (ChannelBuffer) vector.get(2);//gameCharacter
            if (gameCharacter instanceof PlayerInstance){//玩家
                PlayerInstance player= (PlayerInstance) gameCharacter;
                for (GameCharacter objCharacter:getGameCharacterFastList()){//objCharacter 可能是B ankerAI ，也可能是PlayerInstance
                    if (objCharacter.getID()==player.getID()||objCharacter instanceof BankerAI)continue;
                    //构造bean将player信息推送出去
                    objCharacter.DirectSend(data);
                }
            }else {//同步BankerAI信息
                for (GameCharacter playerInstance:getGameCharacterFastList()){
                    if (playerInstance instanceof BankerAI)continue;
                    //构造bean将bankerAI信息推送出去
                    playerInstance.DirectSend(data);
                }
            }
        }


        public int getCircleUnitID() {
            return circleUnitID;
        }

        public void setCircleUnitID(int circleUnitID) {
            this.circleUnitID = circleUnitID;
        }

        public boolean isOccupancy() {
            return Occupancy;
        }

        public void setOccupancy(boolean occupancy) {
            Occupancy = occupancy;
        }

    }



    public static void main(String[]args){

         Table.test(1);


    }

    public static void test(int i){
        System.out.println(i);
    }



}
